package com.whty.cms.filewps.util;

import com.alibaba.fastjson.JSON;
import com.whty.cms.filewps.common.constants.Consts;
import com.whty.cms.filewps.common.message.ResponseMessage;
import com.whty.cms.filewps.upload.dto.AttachFile;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 在线编辑相关请求方法类
 */
public class WPSEdit {

    private static final Logger LOG = LoggerFactory.getLogger(WPSEdit.class);

    private static String contentType = "application/json";
    public final static String HTTP_HEADER_WPS_DOCS_DATE = "Wps-Docs-Date";
    public final static String HTTP_HEADER_WPS_DOCS_AUTHORIZATION = "Wps-Docs-Authorization";
    public final static String HTTP_HEADER_CONTENT_TYPE = "Content-Type";
    public final static String WPS_SIGNATURE_VERSION = "WPS-4";

    public final static String[] WORD_EXT = {"doc","dot","wps","wpt","docx","dotx","docm","dotm","rtf","txt"};
    public final static String[] EXCEL_EXT = {"xls","xlt","et","xlsx","xltx","xlsm","xltm","csv"};
    public final static String[] PPT_EXT = {"ppt","pptx","pptm","ppsx","ppsm","pps","potx","potm","dpt","dps"};
    public final static String[] PDF_EXT = {"pdf", "ofd"};

    public final static String[] X_EXT = {"jpeg","jpg","png","gif","bmp","tif","tiff","svg","psd",
            "tar","zip","7z","gz","rar",
            "md",
            "c","cpp","java","js","css","lrc","h","asm","s","asp","bat","bas","prg","cmd","xml"};
    private static String appId; // 应用id
    private static String secretKey; // 应用秘钥

    public static void initAppInfo(String appId, String secretKey) {
        WPSEdit.appId = appId;
        WPSEdit.secretKey = secretKey;
    }

    /**
     * 根据文件名，获取文件类型
     * @param ext 文件名
     * @return 文件类型 w p s f
     */
    public static String getFileType(String ext){
        for (String element : WORD_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, element)) {
                return "w";
            }
        }
        for (String item : EXCEL_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, item)) {
                return "s";
            }
        }
        for (String value : PPT_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, value)) {
                return "p";
            }
        }
        for (String s : PDF_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, s)) {
                return "f";
            }
        }
        for (String s : X_EXT) {
            if (StringUtils.equalsIgnoreCase(ext, s)) {
                return "x";
            }
        }
        return null;
    }

    /**
     * 获取请求body MD5
     * @param content 请求body
     * @return
     */
    private static String getContentSha256(String content) {
        if (StringUtils.isBlank(content)) {
            return "";
        } else {
            return DigestUtils.sha256Hex(content);
        }
    }

    /**
     * 获取日期字符串
     *
     * @param date
     * @return
     */
    private static String getGMTDateString(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        return format.format(date) + " GMT";
    }

    /**
     * 获取WPS Authorization
     * @param ver
     * @param httpMethod
     * @param uriWithQuerystring
     * @param contentSha256
     * @param dateString
     * @param contentType
     * @return
     */
    private static String getWpsAuthorization(String ver, String httpMethod, String uriWithQuerystring, String contentSha256, String dateString, String contentType) throws Exception {
        String signatureStr = String.format("%s%s%s%s%s%s",ver,httpMethod,
                uriWithQuerystring,contentType,dateString,contentSha256);
        LOG.info("要签名的值:{}",signatureStr);
        return String.format("WPS-4 %s:%s",appId,HMacUtils.HMACSHA256(signatureStr,secretKey));
    }

    /**
     * 获取签名请求头
     *
     * @param uriWithQuerystring 请求url，带querystring
     * @param content            请求body
     * @param contentType        默认为 application/json
     * @return
     */
    public static Map<String, String> getSignatureHeaders(String uriWithQuerystring, String httpMethod, String content, String contentType) throws Exception {
        if (uriWithQuerystring == null) {
            uriWithQuerystring = "";
        }
        if (contentType == null) {
            contentType = "application/json";
        }
        String contentSha256 = getContentSha256(content);
        String dateString = getGMTDateString(new Date());
        String authorization = getWpsAuthorization(WPS_SIGNATURE_VERSION,httpMethod,
                uriWithQuerystring,contentSha256, dateString, contentType);

        Map<String, String> headers = new HashMap<>();
        headers.put(WPSEdit.HTTP_HEADER_WPS_DOCS_AUTHORIZATION, authorization);
        headers.put(WPSEdit.HTTP_HEADER_CONTENT_TYPE, contentType);
        headers.put(WPSEdit.HTTP_HEADER_WPS_DOCS_DATE, dateString);
        LOG.info("签名结果: {} -> {}",WPSEdit.HTTP_HEADER_WPS_DOCS_AUTHORIZATION,authorization);
        LOG.info("签名结果: {} -> {}",WPSEdit.HTTP_HEADER_CONTENT_TYPE,contentType);
        LOG.info("签名结果: {} -> {}",WPSEdit.HTTP_HEADER_WPS_DOCS_DATE,dateString);
        return headers;
    }


    public static String getpreviewUrl(AttachFile attach) {
        String type = getFileType(attach.getFileExt());
        String url = "https://fc-wpsonline.huijiaoyun.com/open/api/preview/v1/files/" + attach.getFid() + "/link?type=" + type;

        //获取uri路径
        String path = url.substring(url.indexOf("open")+4);

        String date = getGMTDateString(new Date());
        //open不参与签名，做替换处理
        if (path.startsWith("/open")) {
            path = path.replace("/open", "");
        }
        String sha256body;
        //body为空则为空，否则返回sha256(body)

        sha256body = "";
        //hmac-sha256(secret_key, Ver + HttpMethod + URI + Content-Type + Wps-Date + sha256(HttpBody))
        String signature = null;
        try {
            signature = HMacUtils.HMACSHA256("WPS-4GET" + path + contentType + date + sha256body, "u4lrIS4ZB8IRz0N9MR2hGfuIAPyFGNOx");
            HttpGet httpGet = new HttpGet(url);
            CloseableHttpClient client = HttpClients.createDefault();
            CloseableHttpResponse response;
            String responseContent = "";
            httpGet.addHeader("Content-Type", "application/json");
            httpGet.addHeader("Wps-Docs-Date", date);
            httpGet.addHeader("Wps-Docs-Authorization", String.format("WPS-4 %s:%s", "XNDQWNASOOCKQGSN", signature));
            response = client.execute(httpGet);
            HttpEntity entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
            System.out.println("请求预览地址返回结果：" + responseContent);
            if (org.apache.commons.lang3.StringUtils.isNotBlank(responseContent)) {
                JSONObject jsonObj = JSONObject.fromObject(responseContent);
                if (jsonObj.optInt("code") == 200) {
                    JSONObject data = jsonObj.optJSONObject("data");
                    String previewUrl = data.optString("link");
                    return previewUrl;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    public static String preload(String fid) throws Exception {
        String url = "https://fc-wpsonline.huijiaoyun.com/open/api/preview/v2/files/" + fid + "/versions/1/preload";
        //获取uri路径
        String path = "/api/preview/v2/files/" + fid + "/versions/1/preload";

        String date = getGMTDateString(new Date());
        //open不参与签名，做替换处理
        if (path.startsWith("/open")) {
            path = path.replace("/open", "");
        }
        String sha256body;
        //body为空则为空，否则返回sha256(body)

        JSONObject requestBody = new JSONObject();
        requestBody.put("webhook", "https://filecenter.huijiaoyun.com/filecenter/v4/v1/3rd/file/version/1");
        sha256body = JSON.toJSONString(requestBody);

        //hmac-sha256(secret_key, Ver + HttpMethod + URI + Content-Type + Wps-Date + sha256(HttpBody))
        String signature = null;
        try {
            String signStr = "WPS-4POST" + path + contentType + date + getContentSha256(sha256body);
            System.out.println("签名串：" + signStr);
            signature = HMacUtils.HMACSHA256(signStr, "u4lrIS4ZB8IRz0N9MR2hGfuIAPyFGNOx");
        } catch (Exception e) {
            e.printStackTrace();
        }

        HttpPost request = new HttpPost(url);

        String responseContent = "";
        request.addHeader("Content-Type", "application/json");
        request.addHeader("Wps-Docs-Date", date);
        request.addHeader("Wps-Docs-Authorization", String.format("WPS-4 %s:%s", "XNDQWNASOOCKQGSN", signature));
        request.setEntity(new StringEntity(sha256body, "UTF-8"));
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = client.execute(request);
        HttpEntity entity = response.getEntity();
        responseContent = EntityUtils.toString(entity, "UTF-8");
        System.out.println("请求预览地址返回结果：" + responseContent);
        if (org.apache.commons.lang3.StringUtils.isNotBlank(responseContent)) {
            JSONObject jsonObj = JSONObject.fromObject(responseContent);
            if (jsonObj.optInt("code") == 200) {
                JSONObject data = jsonObj.optJSONObject("data");
                String previewUrl = data.optString("link");
                return previewUrl;
            }
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        save("717157075171409920","ppt");
        //JSONArray arr = getCooperators("717157075171409920");
        //System.out.println(url);
    }


    //获取在线编辑链接
    public static String getEditUrl(AttachFile attach) throws Exception {
        String url;
        String type = getFileType(attach.getFileExt());
        if(StringUtils.isBlank(attach.getPermission())){
             url = "https://fc-wpsonline.huijiaoyun.com/open/api/edit/v1/files/" + attach.getFid() + "/link?type=" + type+"&_w_third_userId="+attach.getUserId()+"&_w_third_userName="+URLEncoder.encode(attach.getUserName())
                    +"&_w_third_avatarUrl="+attach.getAvatarUrl()+"&_w_third_fileName="+URLEncoder.encode(attach.getFileName())+"&_w_third_resId="+attach.getResId()+"&_w_third_from="+attach.getFrom();
        }else{
             url = "https://fc-wpsonline.huijiaoyun.com/open/api/edit/v1/files/" + attach.getFid() + "/link?type=" + type+"&_w_third_userId="+attach.getUserId()+"&_w_third_userName="+URLEncoder.encode(attach.getUserName())
                    +"&_w_third_avatarUrl="+attach.getAvatarUrl()+"&_w_third_fileName="+URLEncoder.encode(attach.getFileName())+"&_w_third_resId="+attach.getResId()+"&_w_third_from="+attach.getFrom()+"&_w_third_permission="+attach.getPermission();
        }


        String path = url.substring(url.indexOf("open")+4);
        //获取uri路径
        //String path = "/api/edit/v1/files/" +  attach.getFid() + "/link?type=" + type+"&_w_third_userId="+attach.getUserId()+"&_w_third_userName="+ URLEncoder.encode(attach.getUserName())+"&_w_third_avatarUrl="+attach.getAvatarUrl();

        String date = getGMTDateString(new Date());
        //open不参与签名，做替换处理
        if (path.startsWith("/open")) {
            path = path.replace("/open", "");
        }
        String sha256body = "";
        //body为空则为空，否则返回sha256(body)

        //hmac-sha256(secret_key, Ver + HttpMethod + URI + Content-Type + Wps-Date + sha256(HttpBody))
        String signature = null;
        try {
            String signStr = "WPS-4GET" + path + contentType + date + sha256body;
            System.out.println("签名串：" + signStr);
            signature = HMacUtils.HMACSHA256(signStr, "u4lrIS4ZB8IRz0N9MR2hGfuIAPyFGNOx");
        } catch (Exception e) {
            e.printStackTrace();
        }

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response;
        String responseContent = "";
        httpGet.addHeader("Content-Type", "application/json");
        httpGet.addHeader("Wps-Docs-Date", date);
        httpGet.addHeader("Wps-Docs-Authorization", String.format("WPS-4 %s:%s", "XNDQWNASOOCKQGSN", signature));
        response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();

        responseContent = EntityUtils.toString(entity, "UTF-8");
        System.out.println("请求预览地址返回结果：" + responseContent);
        if (org.apache.commons.lang3.StringUtils.isNotBlank(responseContent)) {
            JSONObject jsonObj = JSONObject.fromObject(responseContent);
            if (jsonObj.optInt("code") == 200) {
                JSONObject data = jsonObj.optJSONObject("data");
                String previewUrl = data.optString("link");
                return previewUrl;
            }
        }
        return null;
    }


    //获取在线协作人数
    public static JSONArray getCooperators(String fid) throws Exception {
        //String type = getFileType(fileExt);
        String url = "https://fc-wpsonline.huijiaoyun.com/open/api/edit/v2/files/" + fid + "/cooperators";

        //获取uri路径
        String path = "/api/edit/v2/files/" + fid + "/cooperators";

        String date = getGMTDateString(new Date());
        String sha256body = "";
        //body为空则为空，否则返回sha256(body)



        //hmac-sha256(secret_key, Ver + HttpMethod + URI + Content-Type + Wps-Date + sha256(HttpBody))
        String signature = null;
        try {
            String signStr = "WPS-4GET" + path + contentType + date + sha256body;
            System.out.println("签名串：" + signStr);
            signature = HMacUtils.HMACSHA256(signStr, "u4lrIS4ZB8IRz0N9MR2hGfuIAPyFGNOx");
        } catch (Exception e) {
            e.printStackTrace();
        }

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response;
        String responseContent = "";
        httpGet.addHeader("Content-Type", "application/json");
        httpGet.addHeader("Wps-Docs-Date", date);
        httpGet.addHeader("Wps-Docs-Authorization", String.format("WPS-4 %s:%s", "XNDQWNASOOCKQGSN", signature));
        response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();

        responseContent = EntityUtils.toString(entity, "UTF-8");
        System.out.println("请求预览地址返回结果：" + responseContent);
        if (org.apache.commons.lang3.StringUtils.isNotBlank(responseContent)) {
            JSONObject jsonObj = JSONObject.fromObject(responseContent);
            if (jsonObj.optInt("code") == 200) {
                JSONObject data = jsonObj.optJSONObject("data");
                JSONArray previewUrl = data.optJSONArray("users");
                return previewUrl;
            }
        }
        return null;
    }


    //强制刷新接口
    public static ResponseMessage refresh(String fid) throws Exception {
        ResponseMessage result = new ResponseMessage();
        //String type = getFileType(fileExt);
        String url = "https://fc-wpsonline.huijiaoyun.com/open/api/edit/v2/files/" + fid + "/refresh";

        //获取uri路径
        String path = url.substring(url.indexOf("open")+4);

        String date = getGMTDateString(new Date());
        String sha256body = "";
        //body为空则为空，否则返回sha256(body)



        //hmac-sha256(secret_key, Ver + HttpMethod + URI + Content-Type + Wps-Date + sha256(HttpBody))
        String signature = null;
        try {
            String signStr = "WPS-4POST" + path + contentType + date + sha256body;
            System.out.println("签名串：" + signStr);
            signature = HMacUtils.HMACSHA256(signStr, "u4lrIS4ZB8IRz0N9MR2hGfuIAPyFGNOx");
        } catch (Exception e) {
            e.printStackTrace();
        }

        HttpPost request = new HttpPost(url);

        String responseContent = "";
        request.addHeader("Content-Type", "application/json");
        request.addHeader("Wps-Docs-Date", date);
        request.addHeader("Wps-Docs-Authorization", String.format("WPS-4 %s:%s", "XNDQWNASOOCKQGSN", signature));
        //request.setEntity(new StringEntity(sha256body, "UTF-8"));
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = client.execute(request);
        HttpEntity entity = response.getEntity();

        responseContent = EntityUtils.toString(entity, "UTF-8");
        System.out.println("强制刷新返回结果：" + responseContent);
        if (org.apache.commons.lang3.StringUtils.isNotBlank(responseContent)) {
            JSONObject jsonObj = JSONObject.fromObject(responseContent);
            if (jsonObj.optInt("code") == 200) {
                JSONObject data = jsonObj.optJSONObject("data");
                return ResponseMessage.returnMessage(result, "000000", "成功", data);
            }else{
                return ResponseMessage.returnMessage(result, "000000","没有人打开文件，不能刷新","" );
            }
        }
        return null;
    }


    //主动保存接口
    public static ResponseMessage save(String fid,String fileExt) throws Exception {
        ResponseMessage result = new ResponseMessage();
        String type = getFileType(fileExt);
        String url = "https://fc-wpsonline.huijiaoyun.com/open/api/edit/v1/file/save?file_id="+fid+"&timeout=600s&type="+type;

        //获取uri路径
        String path = "/api/edit/v1/file/save?file_id="+fid+"&timeout=600s&type="+type;

        String date = getGMTDateString(new Date());
        String sha256body = "";

        String signature = null;
        try {
            String signStr = "WPS-4POST" + path + contentType + date + sha256body;
            System.out.println("签名串：" + signStr);
            signature = HMacUtils.HMACSHA256(signStr, "u4lrIS4ZB8IRz0N9MR2hGfuIAPyFGNOx");
        } catch (Exception e) {
            e.printStackTrace();
        }

        HttpPost request = new HttpPost(url);

        String responseContent = "";
        request.addHeader("Content-Type", "application/json");
        request.addHeader("Wps-Docs-Date", date);
        request.addHeader("Wps-Docs-Authorization", String.format("WPS-4 %s:%s", "XNDQWNASOOCKQGSN", signature));

        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = client.execute(request);
        HttpEntity entity = response.getEntity();

        responseContent = EntityUtils.toString(entity, "UTF-8");
        System.out.println("请求预览地址返回结果：" + responseContent);
        if (org.apache.commons.lang3.StringUtils.isNotBlank(responseContent)) {
            JSONObject jsonObj = JSONObject.fromObject(responseContent);
            if (jsonObj.optInt("code") == 200) {
                JSONObject data = jsonObj.optJSONObject("data");
                return ResponseMessage.returnMessage(result, "000000", "成功", data);
            }
        }
        return null;
    }
}
